# 创建时间:2023/3/20 23:21
# 创建人:天霄
# 计划 :SenjoTwintail
# 文件 :Directory.py
# 基于 Python 3.8.2
# ========================================
# 宿舍界面
# ========================================
from vars import *
import math
import textwrap
import asyncio
import pygame
from pygame import freetype

from Api import savings, uiApi
from BasePygame.Gamer import first, PageDict, SpriteSoldier, SpriteCommon, change_image, LoadImage, loadHalfImage, \
    imageLoad_from_plist, load
from BasePygame.Public import flagBox, fontDefault, fontB
from Common.Common import text2paragraph
from PyGameUI.Use import effect, levelsCalculator as lvCc
from PyGameUI.Use.AsyncGenerate import genAsync
from PyGameUI.Use.MusicBox import MusicBox
from PyGameUI.Use.SoldierPaths import SoldierPaths, AllSoldiersImagesPaths
from PyGameUI.Use.SurfaceGenerater import generate_list_normal_1in1 as gln, generate_list_with_mask_same1in1 as glwm, \
    update_location_w


class DirectoryPage(PageDict):
    """宿舍界面"""

    def __init__(self, touch: SpriteCommon):
        """宿舍界面

        :param touch: 鼠标精灵
        """
        self.nowClothCode = savings.kanban
        self.soldierHaveHalfHead = AllSoldiersImagesPaths()  # ******
        self.nowInfo = self.soldierHaveHalfHead.getInfoBycode(self.nowClothCode)
        '''当前角色信息字典'''
        self.soldierPaths = SoldierPaths(self.nowClothCode, savings.language)
        self.nowRoleCode = self.soldierPaths.get_soldierCode(self.nowClothCode)
        self.nowRoleRecord = []
        '''当前的角色记录：犯罪记录/角色故事'''
        self.nowFavorExp = savings.get_favorEXP(self.nowInfo['job'], self.nowRoleCode)
        '''当前角色的好感度经验值'''
        bgsurface = change_image(CONST.PATH.SCENE_BG_ROOT / self.nowInfo['favorBg'])
        super().__init__(bgsurface)
        self.switchAlready = False
        self.switchTo = 'list'
        '''切换到哪个界面====>
            list：Room List，右侧列表界面。
            main：主界面，按钮和信息栏。
            cv：声音预览。
            to_view：view界面前的中间状态，几乎是一瞬间。
            view：纯净预览，只有背景和军士。
            dress：换装界面。
            
            detail_guilty：犯罪记录
            detail_story：角色故事 '''
        self.dressup_switch_to = 'cloth'
        '''左侧换装时切换标记（cloth-服装，scene-场景）'''
        self.effectsFunctionDict = {}
        '''所有特效展示函数'''
        self.allow_touch_kanban = True
        self.touch = touch
        self.kanban = SpriteSoldier(self.nowClothCode, self.soldierPaths.initImage, 'half')
        self.kanban_image = self.kanban.image
        self.kanban_sound = None
        self.kanban_change_flag = False
        self.kanban_stay_t = self.progress_t = pygame.time.get_ticks()
        self.musicBox = MusicBox()
        self.add(self.kanban, 'kanban')

        self.roomList_w = self.detailList_w = self.dressupList_w = 0
        self.choosed = None
        self.dragging = False
        self.left_buttons = self.right_bars = self.other_buttons = []
        self.soldierList = self.cloth_icon = list()
        self.scenebg_list = genAsync.results.get('favor_scenebg_list')
        self.scenebg_list.sort(key=lambda c: c.objectName)
        self.roomlist_mask = None
        asyncio.run(self.main())

    async def main(self):
        """初始化"""
        await asyncio.gather(self._get_base1(), self._get_base2(), self._get_base3(), self._get_base4(),
                             self._get_base5(), self._get_base6(), self._get_base7(), self._get_base8(),
                             self._update_soldierList(), )

    async def _get_base1(self):
        """获取基本图像1：列表布局"""
        self.all_listLayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlistlayer'))
        self.all_listLayerLoads['favorlistbg'] = LoadImage(change_image(uiApi.getUiPathPlist('favorlistbg')[0]))

    async def _get_base2(self):
        """获取基本图像2：列表道具"""
        self.all_listItemLayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlistitemlayer'))

    async def _get_base3(self):
        """获取基本图像3：公共元素"""
        self.all_commonlayer = imageLoad_from_plist(*uiApi.getUiPathPlist('commonlayer'))  # 各种公共元素
        self.commontop = LoadImage(change_image(uiApi.getUiPathPlist('commontop')[0]))  # 公共顶部栏

    async def _get_base4(self):
        """获取基本图像4：宿舍主界面"""
        self.all_favorlayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlayer'))

    async def _get_base5(self):
        """获取基本图像5：宿舍主界面2"""
        self.all_favorlayer2Loads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlayer2'))

    async def _get_base6(self):
        """获取基本图像6：详情"""
        self.all_favordetaillayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favordetaillayer'))

    async def _get_base7(self):
        """获取基本图像7：军士信息"""
        self.all_favorinfolayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favoreventlistitemlayer'))

    async def _get_base8(self):
        """获取基本图像8：背景单图"""
        self.clothbg = LoadImage(change_image(uiApi.getUiPathPlist('clothbg')[0]))  # 换装背景
        self.talklistitembg = LoadImage(change_image(uiApi.getUiPathPlist('talklistitembg')[0]))  # 语音背景
        self.favorRecordBg2 = LoadImage(change_image(uiApi.getUiPathPlist('favorRecordBg2')[0]))  # 角色故事6背景
        self.favorRecordBg1 = LoadImage(change_image(uiApi.getUiPathPlist('favorRecordBg1')[0]))  # 角色故事纯背景

    async def _get_base_all(self):
        """获取基本图像-所有（未启用）"""
        self.all_listLayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlistlayer'))
        self.all_listLayerLoads['favorlistbg'] = LoadImage(change_image(uiApi.getUiPathPlist('favorlistbg')[0]))
        self.all_listItemLayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlistitemlayer'))
        self.all_commonlayer = imageLoad_from_plist(*uiApi.getUiPathPlist('commonlayer'))  # 各种公共元素
        self.commontop = LoadImage(change_image(uiApi.getUiPathPlist('commontop')[0]))  # 公共顶部栏

        self.all_favorlayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlayer'))
        self.all_favorlayer2Loads = imageLoad_from_plist(*uiApi.getUiPathPlist('favorlayer2'))
        self.all_favordetaillayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favordetaillayer'))
        self.all_favorinfolayerLoads = imageLoad_from_plist(*uiApi.getUiPathPlist('favoreventlistitemlayer'))

        self.clothbg = LoadImage(change_image(uiApi.getUiPathPlist('clothbg')[0]))  # 换装背景
        self.talklistitembg = LoadImage(change_image(uiApi.getUiPathPlist('talklistitembg')[0]))  # 语音背景
        self.favorRecordBg2 = LoadImage(change_image(uiApi.getUiPathPlist('favorRecordBg2')[0]))  # 角色故事6背景
        self.favorRecordBg1 = LoadImage(change_image(uiApi.getUiPathPlist('favorRecordBg1')[0]))  # 角色故事纯背景

    async def _update_soldierList(self):
        """生成room_list图像，在初始化和变更服装后需刷新"""
        allHalfHeads = self.soldierHaveHalfHead.refresh_halfheads()
        self.soldierList.clear()
        listbg = self.all_listItemLayerLoads['listbg']  # 列表数据背景
        list2bg = self.all_listItemLayerLoads['list2bg']  # 头像框
        namebg = self.all_listItemLayerLoads['namebg']  # 姓名栏
        for soldier in allHalfHeads:
            name, file, clothcode, job, nature, level, exp, bg = soldier
            name_text = fontDefault.render(name, 'white', size=25)[0]
            level_text = fontDefault.render(str(level), 'white', size=25)[0]
            nameBar = namebg.copy().draw_in(name_text, (67, 13)).draw_in_RectCenter(level_text, (17, 13, 30, 26)). \
                rechange(0, 0.85)
            halfhead = LoadImage(change_image(file)).draw_sameAs_size(list2bg)
            # halfhead = halfhead.draw_in_center(list2bg.as_size(halfhead))
            one = listbg.copy().draw_in(halfhead, (70, 8)).draw_in(nameBar, (210, 25))
            one.objectName = clothcode
            one.connect(lambda: None)
            self.soldierList.append(one)
        self.kanban_stay_t = pygame.time.get_ticks()

    # async def _scenebg_init(self):
    #     """初始化时生成场景背景缩略图"""
    #     self.scenebg_list = await genAsync.generate_bgs()

    def __del__(self):
        """销毁时处理"""
        for one in self.SurfaceDict:
            try:
                self.SurfaceDict.get(one).kill()
            except:
                continue
        del self.all_listLayerLoads, self.all_listItemLayerLoads, self.all_commonlayer, self.soldierList
        super().__del__()

    def drawAll(self):
        """绘制所有图像"""
        self.draw_bg()
        flagBox.fondled_where = self.kanban.touchWhere(*self.touch.rect.topleft)
        flagBox.fondled = pygame.sprite.collide_mask(self.touch, self.kanban)
        self.draw_roomList()
        if flagBox.clicked: self.dragging = False
        self.draw_kanban()
        self.draw_main()
        self.draw_record()
        self.draw_dressing()
        self.draw_cv_talk()
        self.checks()
        self.show_effects()
        self.switchTo = self.switchTo.replace('to_', '')

    def draw_bg(self):
        """绘制背景："""
        screen = self.screen
        screen.blit(self.bg, (0, 0))
        if self.switchTo == 'view':
            return
        favortitle = self.all_favorlayerLoads['favortitle']  # “宿舍”
        screen.blit(self.commontop.copy().draw_in_center(favortitle.surface).surface, (0, 0))
        self.btn_return = self.all_commonlayer['return']  # 返回按钮
        self.btn_return.connect(self.click_btn_return)
        self.btn_return.setTopleft((18, 18))
        screen.blit(self.btn_return.surface, self.btn_return.rect)

    def draw_roomList(self):
        """绘制roomlist"""
        if self.switchTo in ('view', 'cv'):
            return
        screen = self.screen
        listLayer = self.all_listLayerLoads

        bg1 = listLayer['bg1']  # 侧边栏大背景
        bg2 = listLayer['bg2']  # 侧边栏左侧弧线
        bg3 = listLayer['favorlistbg']  # 侧边栏黑色背景
        favorlisttitle = listLayer['favorlisttitle']  # “RoomList”
        progress = listLayer['progress']  # 滚动条内条
        progressbg = listLayer['progressbg']  # 滚动条外条
        projection1 = listLayer['projection1']  # 列表每条数据的底线
        text = listLayer['text']  # “获得3军阶以上军士可开启该宿舍”

        self.bg1_roomlist = bg1.copy()
        progress_stay_time = pygame.time.get_ticks() - self.progress_t
        '''上次滚动时间间隔'''

        space, whole_list_height = 18, 0  # 空隙高度；军士list总高度
        for b in self.soldierList:
            whole_list_height += b.surface.get_size()[1]
        whole_list_height += (len(self.soldierList) - 1) * space
        # 捕获鼠标滚动/拖拽
        init_w = 0 + self.roomList_w
        rect = bg3.rect
        func_show_list = lambda: None
        if self.switchTo in ('main', 'dress'):
            rect.bottomleft = (1094, first.screen_sizeRect.h)
            self.bg1_roomlist.rect.bottomleft = (1094, first.screen_sizeRect.h)
            self.bg1_roomlist.clickRect = pygame.Rect(1094, 54, 540, 600)
            income = self.all_listLayerLoads['income']  # 收起侧边栏时，向左的箭头（深色）
            self.income2 = self.all_listLayerLoads['income2']  # 收起侧边栏时，向左的箭头（浅色）

            def func_show_list():
                # 绘制展开按钮
                income.surface.set_alpha(255 * abs(math.cos(pygame.time.get_ticks() / 300)))
                self.income2.surface.set_alpha(255 * abs(math.sin(pygame.time.get_ticks() / 300)))
                income.setTopleft((1070, 333))
                self.income2.setTopleft((1070, 333))
                # income2.clickRect.size = income2.clickRect.size[0]*2, income2.clickRect.size[1]*2
                screen.blit(income.surface, income.rect)
                screen.blit(self.income2.surface, self.income2.rect)
                self.income2.connect(self.click_btn_showlist)
        elif self.switchTo == 'list':  # 捕获鼠标拖拽或滚动滚轮事件，更新纵坐标
            rect.bottomright = first.screen_sizeRect.bottomright
            self.bg1_roomlist.rect.bottomright = first.screen_sizeRect.bottomright
            self.bg1_roomlist.clickRect = pygame.Rect(617, 54, 540, 600)
            min_w = rect.h - whole_list_height
            clickable = self.bg1_roomlist.inClickRect()

            def func():
                if progress_stay_time > 1000: self.progress_t = pygame.time.get_ticks()

            self.roomList_w = update_location_w(self.roomList_w, clickable, 20, min_w, dragging_function=func)
        else:
            return

        self.roomlist_mask = LoadImage(glwm(bg3.surface, self.soldierList, space, bg_alpha=40, first_keep_top=init_w,
                                            function_locate_each=lambda one, y: one.setTopleft((rect[0], rect[1] + y))))
        ti = 1
        progress = LoadImage(progress.rechange(90, 1))
        if whole_list_height > rect.h:
            ti = max(0.2, rect.h / whole_list_height) * progressbg.rect.h / progress.rect.h
        progress.drag(ti, 'h')
        keep_up = 4  # 滚动条与上下保持的空隙像素
        ty = abs(init_w) / (whole_list_height - rect.h) * (progressbg.rect.h - progress.rect.h - keep_up * 2)
        progressbg = progressbg.copy().draw_in(progress, (2, ty + keep_up))
        # al = 300*math.cos(0.0005*(min(max(progress_stay_time,1000),4000)-1000))-45  # 三角函数，很慢
        # al = 256-2**(0.004*(min(progress_stay_time,3000)-1000))  # 指数函数，慢
        # al = 275+1/(0.00003*(min(progress_stay_time,2878)-3000))  # 幂函数（双曲线），还行
        al = 40 * math.log(2501 - min(progress_stay_time, 2500), 2)  # 对数函数，消失迅速，合适
        progressbg.surface.set_alpha(al)

        self.roomlist_mask.setTopleft((self.bg1_roomlist.rect[0] + 7, self.bg1_roomlist.rect[1] + 103))
        self.bg1_roomlist = self.bg1_roomlist.draw_in(favorlisttitle, (172, 15)).draw_in(text, (125, 56)). \
            draw_in(self.roomlist_mask, (7, 103)).draw_in(bg2, (0, 0)).draw_in(progressbg, (465, 20))
        screen.blit(self.bg1_roomlist.surface, self.bg1_roomlist.rect)
        func_show_list()
        # self.choose_to_move({'bg4': LoadImage(bg4)}/)  #(641, 158, 533, 482)
        # screen.blit(bg3.surface, bg3.rect)

    def choose_to_move(self, imageLoads: dict):
        """选定目标使用键盘移动"""
        for k in imageLoads:
            imageLoad: LoadImage = imageLoads[k]
            if imageLoad.inClickRect() and flagBox.clicked:
                self.choosed = imageLoad
                break
        if not self.choosed:
            return
        if not any(flagBox.wasd):
            return
        rect = self.choosed.rect
        if flagBox.wasd[0]:
            rect[1] -= 1
        if flagBox.wasd[1]:
            rect[0] -= 1
        if flagBox.wasd[2]:
            rect[1] += 1
        if flagBox.wasd[3]:
            rect[0] += 1
        print(f'[选定移动]原点位置：{rect}')
        self.choosed.setTopleft((rect[0], rect[1]))

    def draw_kanban(self):
        """绘制看板娘"""
        if self.kanban_change_flag:
            self.kanban.change(self.kanban_image)
            if self.kanban_sound: self.musicBox.playMusic(self.kanban_sound)
            self.kanban_sound = None
            self.kanban_change_flag = False
            self.kanban_stay_t = pygame.time.get_ticks()
        kanbanRect = self.kanban.rect
        kanbanRect.midleft = self.screen_sizeRect.midleft
        if self.switchTo in ('dress', 'cv'):
            kanbanRect.midleft = self.screen_sizeRect.center
        self.screen.blit(self.kanban.image, kanbanRect)

    def main_soldierInfoBars(self):
        """main-军士信息栏"""
        all_favordetaillayer = self.all_favordetaillayerLoads
        all_favorinfolayer = self.all_favorinfolayerLoads
        base_info = all_favordetaillayer['synopsisbg']  # 信息的面板

        bg4 = all_favorinfolayer['bg4']  ## 公共白板
        bg10 = all_favorinfolayer['bg10']  ## 粉红背景
        bg9 = all_favorinfolayer['bg9']  ## 灰色背景
        commonnotbg = all_favorinfolayer['commonnotbg']  ## 公共上锁白板
        icon = all_favorinfolayer['icon']  ## 白色星星
        touch2 = all_favorinfolayer['touch2']  # “Touch”

        name = self.nowInfo["name"]
        age = self.nowInfo["age"]
        constellation = self.nowInfo["constellation"]
        birthday = self.nowInfo["birthday"]
        blood_type = self.nowInfo["blood_type"]
        height = self.nowInfo["height"]
        weight = self.nowInfo["weight"]
        cup = self.nowInfo["cup"]
        interest = self.nowInfo["interest"]
        dream: str = self.nowInfo["dream"]
        like = self.nowInfo["like"]
        dislike = self.nowInfo["dislike"]
        phantasy = self.nowInfo["phantasy"]
        favorLevel = self.nowInfo["favorLevel"]

        tsize = (140, 32)
        fg = (63, 38, 18)

        stP = lambda s, x, y: (fontDefault.render(s, fg, size=22)[0], pygame.Rect((x, y), tsize))
        stN = lambda s: fontDefault.render(s, fg, size=25)[0]
        stW = lambda s: fontDefault.render(s, 'white', size=25)[0]
        base_info = base_info.copy().draw_in_RectCenter(*stP(name, 98, 16)).draw_in_RectCenter(*stP(age, 344, 16)). \
            draw_in_RectCenter(*stP(constellation, 98, 69)).draw_in_RectCenter(*stP(birthday, 344, 69)). \
            draw_in_RectCenter(*stP(blood_type, 98, 122))
        touch2.surface.set_alpha(255 * abs(math.sin(pygame.time.get_ticks() / 200)))
        commoninfo = bg4.copy().draw_in(bg10, (13, 13)).draw_in(icon, (22, 17)).draw_in(touch2, (424, 51))
        guilt = commoninfo.copy().draw_in(stW('犯罪记录'), (55, 18))
        guilt.connect(self.click_guilt)
        story = commoninfo.copy().draw_in(stW('角色故事'), (55, 18))
        story.connect(self.click_story)
        add = 75
        pinkP, pinkP2 = (13, 40), (13, 40 + add)
        titleP, titleP2 = (13, 10), (13, 10 + add)
        conP, conP2 = (22, 45), (22, 45 + add)
        common2info = bg4.copy().drag(2, 'h')
        common2info = LoadImage(common2info.surface.subsurface((0, 0, common2info.rect[2], common2info.rect[3] - 3)))
        common2info.draw_in(bg10, pinkP).draw_in(bg10, pinkP2)
        common1info = bg4.copy().draw_in(bg10, pinkP)
        h_w_c = common2info.copy().draw_in(stN('身高/体重'), titleP).draw_in(stN('CUP'), titleP2). \
            draw_in(stW(f'{height}/{weight}'), conP).draw_in(stW(cup), conP2)
        interesting = common1info.copy().draw_in(stN('兴趣'), titleP).draw_in(stW(interest), conP)
        dreams = bg4.copy().drag(1.5, 'h').draw_in(bg10.copy().drag(2.2, 'h'), pinkP).draw_in(stN('将来梦想'), titleP)
        n = 19 if len(dream) <= 19 or dream[20] in ('！', '？', '。') else 18
        dream_list = textwrap.wrap(dream, n)
        y = conP[1]
        for line in dream_list:
            dreams.draw_in(stW(line), (conP[0], y))
            y += 30
        l_d = common2info.copy().draw_in(stN('喜欢的事物'), titleP).draw_in(stN('讨厌的事物'), titleP2). \
            draw_in(stW(like), conP).draw_in(stW(dislike), conP2)
        phantasy_people = common1info.draw_in(stN('憧憬的人'), titleP).draw_in(stW(phantasy), conP)
        info_bars = [base_info, guilt, story, h_w_c, interesting, dreams, l_d, phantasy_people]
        return info_bars

    def draw_main(self):
        """绘制宿舍主界面"""
        if self.switchTo not in ('main', 'detail_guilty', 'detail_story'):
            return
        screen = self.screen
        all_favorlayer = self.all_favorlayerLoads
        all_favordetaillayer = self.all_favordetaillayerLoads
        all_favorinfolayer = self.all_favorinfolayerLoads

        site = all_favorlayer['site']  # 设置看板
        sitenot = all_favorlayer['sitenot']  # 设置成功，禁用
        gift = all_favorlayer['gift']  # 礼盒按钮
        # giftnot = all_favorlayer['giftnot']  # 礼盒按钮禁用
        # giftitembg = all_favorlayer['giftitembg']  # 送礼对话框背景
        dressup = all_favorlayer['dressup']  # 换衣按钮
        # dressupnot = all_favorlayer['dressupnot']  # 换衣按钮禁用
        # guard = all_favorlayer['guard']  # 好感上升按钮
        # guardnot = all_favorlayer['guardnot']
        cvbg = all_favorlayer['cvbg']  # cv
        cvicon = all_favorlayer['cvicon']  # cv
        # event = all_favorlayer['event']  # 事件
        # heart = all_favorlayer['heart']  # 爱心
        # heart1 = all_favorlayer['heart1']  # 浅色爱心
        # lock2 = all_favorlayer['lock2']  # 锁，禁用
        # lock4 = all_favorlayer['lock4']  # 锁，白色
        # sound1 = all_favorlayer['sound1']  # 语音喇叭
        # sound2 = all_favorlayer['sound2']
        # sound3 = all_favorlayer['sound3']
        thermometerbg = all_favorlayer['thermometerbg']  # 好感度背景
        thermometer1 = all_favorlayer['thermometer1']  # 好感度的刻度
        view = all_favorlayer['uibutton']  # 右上角view
        # love1 = all_favorlayer['love1']  # 深粉色向右的尖条形图
        # love2 = all_favorlayer['love2']  # 粉色进度条背景
        # love3 = all_favorlayer['love3']  # 粉色进度条
        # love4 = all_favorlayer['love4']  # 有光泽的爱心
        # r01 = all_favorlayer['01']  # 红色1
        # r02 = all_favorlayer['02']  # 红色2
        # r03 = all_favorlayer['03']  # 红色3
        # r04 = all_favorlayer['04']  # 红色4
        # r05 = all_favorlayer['05']  # 红色5
        # b0 = all_favorlayer['0']  # 白色0
        # guard7 = all_favorlayer['guard7']  # 黑框粉色方块
        # guard8 = all_favorlayer['guard8']  # 黑色方块

        tab1_info = all_favordetaillayer['synopsis']  # 信息一览
        tab1_info_sel = all_favordetaillayer['synopsissel']
        tab2_chronicle = all_favordetaillayer['chronicle']  # 私密记事
        tab2_chronicle_sel = all_favordetaillayer['chroniclesel']
        tab3_photo = all_favordetaillayer['gallery']  # 珍贵写真
        tab3_photo_not = all_favordetaillayer['gallerynot']
        tab3_photo_sel = all_favordetaillayer['gallerysel']
        base_info = all_favordetaillayer['synopsisbg']  # 信息的面板
        # commonbg = all_favordetaillayer['commonbg']  # 公共白板
        commonnotbg = all_favordetaillayer['commonnotbg']  # 公共上锁白板
        bg11 = all_favordetaillayer['bg11']  # 宽一点的灰色背景
        lock = all_favordetaillayer['lock']  # 灰色锁

        bg4 = all_favorinfolayer['bg4']  ## 公共白板
        # bg10 = all_favorinfolayer['bg10']  ## 粉红背景
        # bg9 = all_favorinfolayer['bg9']  ## 灰色背景
        # commonnotbg = all_favorinfolayer['commonnotbg']  ## 公共上锁白板
        # icon = all_favorinfolayer['icon']  ## 白色星星
        # touch2 = all_favorinfolayer['touch2']  # “Touch”
        # lock4 = all_favorinfolayer['lock4']  ## 白色锁
        # touch1 = all_favorinfolayer['touch1']  ## “Touch Screen”
        # lowlight = all_favorinfolayer['lowlight']  # 粉红线框
        # starlight = all_favorinfolayer['starlight']  # 十字星

        # 当前信息
        favorLevel = self.nowInfo["favorLevel"]

        # 绘制好感度
        h = favorLevel / 15 * 139
        lovelevel_text = fontDefault.render(str(favorLevel), 'white', style=freetype.STYLE_STRONG, size=40)[0]
        thermometer = LoadImage(change_image(uiApi.getUiPathPlist('thermometer')[0], (0, 139 - h, 73, h)))
        thermometer.surface.set_alpha(240)
        thermometerbg = thermometerbg.copy().draw_custom(thermometer, 'midbottom', (0, -1)). \
            draw_in(thermometer1, (44, 22)).draw_in_RectCenter(lovelevel_text, (6, 82, 64, 45))
        screen.blit(thermometerbg.surface, (482, 92))
        view.setTopleft((1070, 11))
        screen.blit(view.surface, view.rect)

        # 绘制左侧按钮
        set_btn = sitenot
        set_btn.connect(lambda: None)
        if savings.kanban != self.nowClothCode:
            set_btn = site
            set_btn.connect(self.click_site)
        self.left_buttons = [set_btn, gift, dressup]
        self.other_buttons = [cvbg, view]
        if self.switchTo == 'main':
            set_btn.setTopleft((23, 120))
            for index, btn in enumerate(self.left_buttons):
                if index == 0:
                    screen.blit(btn.surface, btn.rect)
                    continue
                btn.setTopleft(self.left_buttons[index - 1].rect.copy().move(0, 100).topleft)
                screen.blit(btn.surface, btn.rect)

        # cvbg.draw_in(cvicon, (0, 0))
        cvbg.setTopleft((17, 596))
        screen.blit(cvbg.surface, cvbg.rect)
        screen.blit(cvicon.surface, (10, 597))
        cv = self.nowInfo.get('cv_jp')
        screen.blit(fontDefault.render(cv, 'white', size=25)[0], (55, 600))

        # 绘制信息底部按钮
        tab1_info_sel.setTopleft((577, 580))
        tab2_chronicle.setTopleft((752, 580))
        tab3_photo_not.setTopleft((925, 580))
        screen.blit(tab1_info_sel.surface, tab1_info_sel.rect)
        screen.blit(tab2_chronicle.surface, tab2_chronicle.rect)
        screen.blit(tab3_photo_not.surface, tab3_photo_not.rect)

        # 连接函数
        gift.connect(self.click_gift)
        dressup.connect(self.click_dressup)

        tab1_info_sel.connect(self.click_tab1_info)
        tab2_chronicle.connect(self.click_tab2_chronicle)
        tab3_photo_not.connect(self.click_tab3_photo)

        cvbg.connect(self.click_cv)
        view.connect(self.click_view)

        # 绘制信息栏
        info_bars = self.main_soldierInfoBars()
        # info_bars = [base_info, guilt, story, h_w_c, interesting, dreams, l_d, phantasy_people]
        '''军士信息栏'''
        self.right_bars = [info_bars[1], info_bars[2], tab1_info_sel, tab2_chronicle, tab3_photo_not]
        '''右侧可点击元素'''

        space, info_height = 18, 0  # 空隙高度；军士所有信息list总高度
        for b in info_bars:
            info_height += b.surface.get_size()[1]
        info_height += (len(info_bars) - 1) * space

        h = 496
        dtlSize = bg4.surface.get_size()[0], h
        self.detailList = LoadImage(pygame.Surface((dtlSize), pygame.SRCALPHA).convert_alpha())
        init_w = 0 + self.detailList_w
        rect = self.detailList.rect
        # 捕获鼠标拖拽或滚动滚轮事件，更新纵坐标
        rect.topleft = (578, 70)
        self.detailList.rect.topleft = (578, 70)
        self.detailList.clickRect = pygame.Rect((578, 70), dtlSize)
        min_w = h - info_height
        clickable = self.detailList.inClickRect()
        if not self.switchTo.startswith('detail'):  # 文字界面禁止滚动
            self.detailList_w = update_location_w(self.detailList_w, clickable, 10, min_w)

        def _f(one, y):
            if one.function: one.setTopleft((rect[0], rect[1] + y))

        detailList_mask = gln(self.detailList.surface, info_bars, space, first_keep_top=init_w, function_locate_each=_f)
        detailList_mask = LoadImage(detailList_mask)
        screen.blit(detailList_mask.surface, rect)

    def draw_record(self):
        """绘制犯罪记录/角色故事"""
        if not self.switchTo.startswith('detail'):
            return
        screen = self.screen
        tt = {'detail_guilty': '犯罪记录', 'detail_story': '角色故事'}
        title_text = tt[self.switchTo]
        title = fontB.render(title_text, (221, 131, 170), size=30)[0]

        self.favorRecordBg2.setBottomright(first.screen_sizeRect.bottomright)
        self.favorRecordBg1.setBottomright(first.screen_sizeRect.midbottom)
        screen.blit(self.favorRecordBg2.surface, self.favorRecordBg2.rect)
        screen.blit(self.favorRecordBg1.surface, self.favorRecordBg1.rect)
        screen.blit(title, (520, 65))

        if not self.nowRoleRecord: return
        conP = (520, 130)
        y = conP[1]
        for lines in self.nowRoleRecord:
            for line in lines:
                screen.blit(fontDefault.render(line.rstrip(), 'white', size=22)[0], (conP[0], y))
                y += 29
            y += 8

    def draw_dressing(self):
        """绘制更衣间"""
        if self.switchTo != 'dress':
            return
        screen = self.screen
        all_favorlayer = self.all_favorlayerLoads
        all_favorlayer2 = self.all_favorlayer2Loads

        # giftitembg = all_favorlayer['giftitembg']  # 送礼对话框背景
        # dressup = all_favorlayer['dressup']  # 换衣按钮
        # dressupnot = all_favorlayer['dressupnot']  # 换衣按钮禁用
        # guard = all_favorlayer['guard']  # 好感上升按钮
        # guardnot = all_favorlayer['guardnot']
        # event = all_favorlayer['event']  # 事件
        # heart = all_favorlayer['heart']  # 爱心
        # heart1 = all_favorlayer['heart1']  # 浅色爱心
        # lock2 = all_favorlayer['lock2']  # 锁，禁用
        # lock4 = all_favorlayer['lock4']  # 锁，白色
        # sound1 = all_favorlayer['sound1']  # 语音喇叭
        # sound2 = all_favorlayer['sound2']
        # sound3 = all_favorlayer['sound3']
        dress = all_favorlayer['dress']  # “着装中...”
        # ru = all_favorlayer['ru']  # 乳
        # rhand = all_favorlayer['rhand']  # 右手
        # rarm = all_favorlayer['rarm']  # 右臂
        # lhand = all_favorlayer['lhand']  # 左手
        # ku = all_favorlayer['ku']  # 内裤
        # yi1 = all_favorlayer['yi1']  # 灰色三角，衣服
        # yi2 = all_favorlayer['yi2']  # 灰色方块，衣服
        # yi3 = all_favorlayer['yi3']  # 灰色く形，衣服
        curtain = all_favorlayer['curtain']  # 窗帘
        replace1 = all_favorlayer['replace1']  # 服装/场景 服装
        replace2 = all_favorlayer['replace2']  # 服装/场景 场景
        # cv1button = all_favorlayer['cv1button']  # 日语/国语，国语
        # cv2button = all_favorlayer['cv2button']  # 日语/国语，日语
        # love1 = all_favorlayer['love1']  # 深粉色向右的尖条形图
        # love2 = all_favorlayer['love2']  # 粉色进度条背景
        # love3 = all_favorlayer['love3']  # 粉色进度条
        # love4 = all_favorlayer['love4']  # 有光泽的爱心
        # guard7 = all_favorlayer['guard7']  # 黑框粉色方块
        # guard8 = all_favorlayer['guard8']  # 黑色方块
        # obtainbutto = all_favorlayer['obtainbutto']  # “前往获取”

        # guard1 = all_favorlayer2['guard1']  # 守护
        # guard2 = all_favorlayer2['guard2']  # 白色透明较长框
        # guard3 = all_favorlayer2['guard3']  # 进度条背景
        # guard4 = all_favorlayer2['guard4']  # 进度条
        # guard5 = all_favorlayer2['guard5']  # 进度条 白
        # guardbg1 = all_favorlayer2['guardbg1']  # 加成面板
        # guardbg2 = all_favorlayer2['guardbg2']  # 下级提升
        # guardbg3 = all_favorlayer2['guardbg3']  # 墨绿框
        # guardbutton = all_favorlayer2['guardbutton']  # [添加守护]
        # guardup = all_favorlayer2['guardup']  # “守护级别提升”
        # guarduplight = all_favorlayer2['guarduplight']  # 守护，白光
        # kuanglight = all_favorlayer2['kuanglight']  # 粉色透明较大框
        # love10 = all_favorlayer2['love10']  # 手指
        # love11 = all_favorlayer2['love11']  # 手指 灰
        # love12 = all_favorlayer2['love12']  # 黑粉爱心
        # love5 = all_favorlayer2['love5']  # 圆框
        # love6light = all_favorlayer2['love6light']  # 发光爱心
        # notlove = all_favorlayer2['notlove']  #
        # progresslight = all_favorlayer2['progresslight']  # 发光细框
        # replacebutton = all_favorlayer2['replacebutton']  # [更换]
        # replacenotbutton = all_favorlayer2['replacenotbutton']  # [已穿着]禁用
        # addbutton = all_favorlayer2['addbutton']  # 绿色添加按钮
        # giftbutton = all_favorlayer2['giftbutton']  # [送礼]
        # giftitemnotbg = all_favorlayer2['giftitemnotbg']  # 大灰框
        # love = all_favorlayer2['love']  # 深色粉红爱心
        # pole = all_favorlayer2['pole']  # 衣架横杆
        # numbg = all_favorlayer2['numbg']  #
        use = all_favorlayer2['use']  # “使用中”
        # bgline = all_favorlayer2['bgline']  #
        # like1 = all_favorlayer2['like1']  # 喜欢/其他 其他
        # like2 = all_favorlayer2['like2']  # 喜欢/其他 喜欢
        # obtainbutto = all_favorlayer2['obtainbutto']  # “前往获取”

        content_frame = LoadImage(pygame.Surface((180, 140), pygame.SRCALPHA).convert_alpha())
        space, whole_height = 30, 0  # 空隙高度；军士所有内容的总高度

        # if 切换到场景: pass
        h = 500
        dtlSize = 180, h
        self.dressupList = LoadImage(pygame.Surface((dtlSize), pygame.SRCALPHA).convert_alpha())
        rect = self.dressupList.rect
        init_w = 0 + self.dressupList_w

        self.cloth_icon = list()
        if self.dressup_switch_to == 'cloth':
            frame_size = (180, 140)
            content_frame = LoadImage(pygame.Surface(frame_size, pygame.SRCALPHA).convert_alpha())
            cloth_iconpaths = self.soldierPaths.clothIconPaths
            sT = lambda s: fontDefault.render(str(s), 'gray', size=25)[0]
            for index, d in enumerate(cloth_iconpaths):
                code, path = d
                icon = LoadImage(change_image(path))
                if code == self.nowClothCode:
                    icon.draw_custom(dress, 'midbottom')
                content = content_frame.copy().draw_custom(icon, 'bottomright').draw_custom(sT(index + 1), 'midleft')
                content.objectName = code
                content.connect(lambda c=content: self.click_dressup_change_cloth(c))
                whole_height += content.surface.get_size()[1]
                self.cloth_icon.append(content)
            whole_height += (len(self.cloth_icon) - 1) * space

        elif self.dressup_switch_to == 'scene':
            for index, scene in enumerate(self.scenebg_list):
                bg = scene.objectName
                scene: LoadImage = scene.copy()
                if bg == self.nowInfo['favorBg']:
                    scene.draw_RectCustom(use, (40, 0, 140, 110), 'midbottom')
                scene.connect(lambda c=bg: self.click_dressup_change_scene(c))
                whole_height += scene.surface.get_size()[1]
                self.cloth_icon.append(scene)
            whole_height += (len(self.cloth_icon) - 1) * space

        # 捕获鼠标拖拽或滚动滚轮事件，更新纵坐标
        rect.topleft = (44, 75)
        self.dressupList.rect.topleft = (44, 75)
        self.dressupList.clickRect = pygame.Rect((44, 75), dtlSize)
        min_w = min(0, h - whole_height)
        clickable = self.dressupList.inClickRect()
        self.dressupList_w = update_location_w(self.dressupList_w, clickable, 50, min_w)

        def _f(one, y):
            if one.function: one.setTopleft((rect[0], rect[1] + y))

        dressupList_mask = gln(self.dressupList.surface, self.cloth_icon, space, first_keep_top=init_w,
                               function_locate_each=_f)
        dressupList_mask = LoadImage(dressupList_mask)

        self.clothbg.setTopleft((0, 0))
        screen.blit(self.clothbg.surface, self.clothbg.rect)
        screen.blit(dressupList_mask.surface, rect)

        replace1.connect(lambda: self.click_dressup_swith_to('scene'))  # 当前服装，点击切换为场景
        replace2.connect(lambda: self.click_dressup_swith_to('cloth'))  # 当前场景，点击切换为服装

        dressup_switchers = {'cloth': replace1, 'scene': replace2}
        self.dressup_switcher = dressup_switchers[self.dressup_switch_to]
        self.dressup_switcher.setTopleft(((31, 585)))
        screen.blit(self.dressup_switcher.surface, self.dressup_switcher.rect)

    def draw_cv_talk(self):
        """绘制cv语音界面"""
        if self.switchTo != "cv":
            return
        screen = self.screen

        self.talklistitembg.setTopleft((0, 0))
        screen.blit(self.clothbg.surface, self.clothbg.rect)

    def checks(self):
        """执行检查点击"""
        if self.btn_return.check('buttonReturn')[0]: return
        if not flagBox.clicked and not self.dragging and flagBox.pressed[0] and flagBox.moving:
            self.dragging = True
        if self.switchTo == 'list' and self.roomlist_mask:
            if flagBox.clickedRight:
                self.switchTo = 'main'
                flagBox.playRightClick = True
                return
            for one in self.soldierList:
                one: LoadImage
                one, _ = one.check('buttonNormal',
                                   not self.dragging and flagBox.clicked and self.roomlist_mask.inClickRect())
                if not one:
                    continue
                load.loading()
                if self.switchTo != 'view': self.switchTo = 'main'
                self.kanban_stay_t = pygame.time.get_ticks()
                # print('======宿舍：main（切换军士）======')
                self.dragging = False
                self.detailList_w = 0
                self.nowClothCode = one.objectName
                self.nowRoleCode = self.soldierPaths.get_soldierCode(self.nowClothCode)
                self.nowInfo = self.soldierHaveHalfHead.getInfoBycode(self.nowClothCode)
                self.nowFavorExp = savings.get_favorEXP(self.nowInfo['job'], self.nowRoleCode)
                # self.bg = change_image(paths.pathJoin(paths.bg_root, self.nowInfo['favorBg']))
                self.bg = change_image(CONST.PATH.SCENE_BG_ROOT / self.nowInfo['favorBg'])
                self.soldierPaths = SoldierPaths(self.nowClothCode, savings.language)
                face, sound = self.soldierPaths.touch_feedback()
                kanban = loadHalfImage(*face, self.soldierPaths.initImage)
                self.kanban.change(kanban.surface)
                print(f'点击了【一个军士“{one.objectName}”】，信息：{self.nowInfo}')
                flagBox.clickable = True
                return
            if flagBox.herePageClickTo is None and flagBox.clicked and not self.bg1_roomlist.inClickRect():
                self.bg1_roomlist.clickRect = pygame.Rect(1094, 54, 540, 600)
                self.switchTo = 'main'
                self.kanban_stay_t = pygame.time.get_ticks()
        elif self.switchTo == 'view':
            if flagBox.where_in != 'kanban' and flagBox.clicked: self.switchTo = 'main'
            if flagBox.clickedRight: self.switchTo, flagBox.playRightClick = 'main', True
        elif self.switchTo.startswith('detail'):
            if flagBox.clickedRight:
                self.switchTo = 'main'
                flagBox.playRightClick = True
                return
            if flagBox.clicked and not self.favorRecordBg2.inClickRect():
                self.switchTo = 'to_main'
                self.kanban_stay_t = pygame.time.get_ticks()
        elif self.switchTo == 'main':
            if self.income2.check('buttonNormal')[0]: return
            if savings.kanban == self.nowClothCode:
                if self.left_buttons[0].check('buttonLock')[0]: return
                for btn in self.left_buttons[1:]:
                    if btn.check('buttonNormal')[0]: return
            else:
                for btn in self.left_buttons:
                    if btn.check('buttonNormal')[0]: return
            for one in self.right_bars[:-2]:
                if one.check('buttonNormal')[0]: return
            for one in self.right_bars[-2:]:
                if one.check('buttonLock')[0]: return
            for one in self.other_buttons:
                if one.check('buttonNormal')[0]: return
        elif self.switchTo == 'dress':
            result, _ = self.income2.check('buttonNormal')
            if result:
                asyncio.run(self._update_soldierList())
                return
            if self.dressup_switcher.check('buttonNormal')[0]: return
            for one in self.cloth_icon:
                if one.check('changeCloth', self.dressupList.inClickRect(), flagIsAdd=True)[0]: return
            if flagBox.clickedRight:
                flagBox.playRightClick = True
            if flagBox.clickedRight or (flagBox.clicked and not self.clothbg.inClickRect()):
                self.switchTo = 'main'
                asyncio.run(self._update_soldierList())
        elif self.switchTo == 'cv':
            if flagBox.clickedRight:
                self.switchTo = 'main'
                flagBox.playRightClick = True
                return
            if self.income2.check('buttonNormal')[0]: return
            if flagBox.clicked and not self.talklistitembg.inClickRect():
                self.switchTo = 'main'
                self.kanban_stay_t = pygame.time.get_ticks()

        if any(flagBox.clickOnce) and flagBox.fondled and flagBox.where_in is None:
            flagBox.where_in = 'kanban'
        if self.allow_touch_kanban and flagBox.clicked and flagBox.fondled_where and flagBox.fondled:
            face, self.kanban_sound = self.soldierPaths.touch_feedback()
            self.kanban_image = loadHalfImage(*face, self.soldierPaths.initImage).surface
            self.kanban_change_flag = True
            if self.switchTo == 'main':  # main界面时，触摸看板添加好感度
                self.favor_level_calculate()
            elif self.switchTo != 'view':  # 非view界面时，触摸看板即回到主界面
                self.switchTo = 'main'
            return
        elif self.switchTo in ('main', 'view') and pygame.time.get_ticks() - self.kanban_stay_t > 90_000:
            face, self.kanban_sound = self.soldierPaths.random_talk()
            self.kanban_image = loadHalfImage(*face, self.soldierPaths.initImage).surface
            self.kanban_change_flag = True
            return

    def favor_level_calculate(self):
        """好感度计算"""
        if flagBox.fondled_where == 'oppai': exp = 1
        elif flagBox.fondled_where == 'others': exp = 2
        elif flagBox.fondled_where == 'head': exp = 3
        else: return
        self.nowFavorExp += exp
        nowLevel = self.nowInfo['favorLevel']
        newLevel, newExp, newLimit = lvCc.favorLevel_count(nowLevel, self.nowFavorExp)
        self.nowFavorExp = newExp
        effect.t_favorLevelExpGet = pygame.time.get_ticks()
        if newLevel > nowLevel:  # 升级了
            self.nowInfo['favorLevel'] = newLevel
            # 特效待补充...

        effunc = lambda: effect.favorLevelExpGet(exp)
        self.effectsFunctionDict['favorLevelExpGet'] = effunc
        savings.update_favorLevel(self.nowInfo['job'], self.nowRoleCode, newLevel, newExp)

    def show_effects(self):
        """展示特效"""
        for effectFunction in self.effectsFunctionDict.values():
            effectFunction()

    def click_btn_return(self):
        """点击了【返回】"""
        print('点击了【返回】')
        if self.switchTo in ('dress', 'cv', 'detail_guilty', 'detail_story'):
            self.switchTo = 'main'
            return
        flagBox.herePageClickTo = 'home'

    def click_btn_showlist(self):
        """点击了【右侧展示列表】"""
        print('点击了【右侧展示列表】')
        self.switchTo = 'list'

    def click_cv(self):
        """点击了【cv】"""
        print('点击了【cv】')
        self.switchTo = 'cv'

    def click_view(self):
        """点击了【view】"""
        print('点击了【view】')
        self.switchTo = 'view'

    def click_site(self):
        """点击了【设置看板】"""
        print('点击了【设置看板】')
        savings.set_Kanban(self.nowClothCode, self.nowInfo['favorBg'])

    def click_gift(self):
        """点击了【送礼】"""
        print('点击了【送礼】(添加服装到yaml)')
        # scode, describe = self.soldierHaveHalfHead.getcodebycode(self.nowCode)
        # if not scode: scode = self.nowCode
        # cloth = {'code': self.nowCode, 'describe': describe}
        # savings.add_newCloth(self.nowJob, scode, cloth)
        # load.loading()

    def click_dressup(self):
        """点击了【换装】"""
        print('点击了【换装】')
        self.switchTo = 'dress'
        self.soldierPaths.refresh_clothIconPath()
        self.dressupList_w = 0

    def click_dressup_swith_to(self, flag):
        """点击了【换装-切换服装/场景】"""
        print('点击了【换装-切换服装/场景】')
        self.dressup_switch_to = flag

    def click_dressup_change_cloth(self, cloth_icon: LoadImage):
        """点击了【换装-变更着装】"""
        print(f'切换了【换装-变更着装】，code：{cloth_icon.objectName}；点击区域：{cloth_icon.clickRect}，'
              f'整个区域：{self.dressupList.clickRect}')
        cloth_code = cloth_icon.objectName
        if savings.kanban == self.nowClothCode:
            savings.set_Kanban(cloth_code, self.nowInfo['favorBg'])
        self.nowClothCode = cloth_code
        savings.change_theMainCloth(self.nowInfo['job'], self.nowRoleCode, cloth_code)
        face = self.soldierPaths.dressup(cloth_code)
        kanban = loadHalfImage(*face, self.soldierPaths.initImage)
        self.kanban.change(kanban.surface)

    def click_dressup_change_scene(self, bgpath):
        """点击了【换装-变更场景】"""
        print(f'切换了【换装-变更场景】')
        self.bg = change_image(CONST.PATH.SCENE_BG_ROOT / bgpath)
        if savings.kanban == self.nowClothCode:
            savings.set_Kanban(self.nowClothCode, bgpath)
        savings.set_favorBg(self.nowInfo['job'], self.nowRoleCode, bgpath)
        self.nowInfo = self.soldierHaveHalfHead.getInfoBycode(self.nowClothCode)

    def click_guilt(self):
        """点击了【犯罪记录】"""
        print('点击了【犯罪记录】')
        self.switchTo = 'detail_guilty'
        guilty_record = self.soldierHaveHalfHead.getRoleRecordContent(self.nowRoleCode, 1)
        if guilty_record:
            self.nowRoleRecord = text2paragraph(guilty_record, 26)
            return
        self.nowRoleRecord = []

    def click_story(self):
        """点击了【角色故事】"""
        print('点击了【角色故事】')
        self.switchTo = 'detail_story'
        story_record = self.soldierHaveHalfHead.getRoleRecordContent(self.nowRoleCode, 2)
        if story_record:
            self.nowRoleRecord = text2paragraph(story_record, 26)
            return
        self.nowRoleRecord = []

    def click_tab1_info(self):
        """点击了【信息一览】"""
        print('点击了【信息一览】')

    def click_tab2_chronicle(self):
        """点击了【私密记事】"""
        print('点击了【私密记事】')

    def click_tab3_photo(self):
        """点击了【珍贵写真】"""
        print('点击了【珍贵写真】')
